home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Libris Britannia 4
/
science library(b).zip
/
science library(b)
/
ASTRONOM
/
H139.ZIP
/
UI101.ZIP
/
IO
/
UI
/
UI_LIST.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-11-04
|
38KB
|
1,384 lines
/***************************************************************
ui_list.c List (Menu) Routines
for the Bywater Graphical User Interface
Copyright (c) 1991, Ted A. Campbell
Bywater Software
P. O. Box 4023
Duke Station
Durham, NC 27706
email: tcamp@hercules.acpub.duke.edu
Copyright and Permissions Information:
All U.S. and international copyrights are claimed by the
author. The author grants permission to use this code
and software based on it under the following conditions:
(a) in general, the code and software based upon it may be
used by individuals and by non-profit organizations; (b) it
may also be utilized by governmental agencies in any country,
with the exception of military agencies; (c) the code and/or
software based upon it may not be sold for a profit without
an explicit and specific permission from the author, except
that a minimal fee may be charged for media on which it is
copied, and for copying and handling; (d) the code must be
distributed in the form in which it has been released by the
author; and (e) the code and software based upon it may not
be used for illegal activities.
***************************************************************/
#include "stdio.h"
#include "bw.h"
#include "gr.h"
#include "kb.h"
#include "dr.h"
#include "ui.h"
#define EXTENSION 1 /* number of pixels to extend
size of each menu item beyond
the height of the text */
#define EL_OFFSET 1
#define ACC 20
#define SL_YSIZE 3
#define SL_XMAX 18
/****************************************************************
ui_ftext() File selection -- text based
****************************************************************/
ui_ftext( x1, y1, x2, y2, specifier, title, m_box,
d_titles, d_entries, max_entries,
background, foreground, highlight )
int x1, y1, x2, y2, background, foreground, highlight, max_entries;
struct menu_box *m_box;
char *specifier, *title;
char **d_titles;
struct dir_ent **d_entries;
{
register int number, c;
/* First check for existence of the file */
number = 0;
if ( dr_first( specifier, d_entries[ number ] ) == FALSE )
{
return FALSE;
}
strcpy( d_titles[ number ], d_entries[ number ]->filename );
/* Find all entries */
number = 1;
while( ( dr_next( d_entries[ number ] ) == TRUE ) && ( number < max_entries ))
{
strcpy( d_titles[ number ], d_entries[ number ]->filename );
++number;
}
m_box->number = number;
m_box->d_titles = d_titles;
m_box->d_entries = d_entries;
m_box->max_entries = max_entries;
/* menu */
c = ui_list( MENU_SLIDERS, x1, y1, x2, y2,
title, number, d_titles, foreground, background, highlight,
m_box, TRUE );
return c;
}
/****************************************************************
ui_list() Scrolling list (menu)
****************************************************************/
ui_list( type, x1, y1, x2, y2, title, number, titles,
foreground, background, highlight, m_box )
int type, x1, y1, x2, y2, foreground, background,
highlight, number;
char *title;
char **titles;
struct menu_box *m_box;
{
int carry_on;
static int c, test;
int mo_xsrc, mo_ysrc;
static int x_pos, y_pos, b_stat, item;
/* draw the list */
uil_draw( type, x1, y1, x2, y2, title, number, titles,
foreground, background, highlight, m_box );
/* activate the list */
uil_activate( m_box, type, 0 );
/* poll while waiting for keyboard or mouse input, carry_on == TRUE */
test = FALSE;
carry_on = TRUE;
while( carry_on == TRUE )
{
if ( kb_rxstat() == TRUE )
{
c = kb_rx();
test = TRUE;
}
else if ( gr_ismouse == TRUE )
{
if ( gr_mouse( SAMPLE, &x_pos, &y_pos, &b_stat )
== TRUE )
{
c = 0;
test = TRUE;
gr_mouse( WAIT, &x_pos, &y_pos, &b_stat );
mo_xsrc = x_pos;
mo_ysrc = y_pos;
gr_mouse( WAIT, &x_pos, &y_pos, &b_stat );
}
}
if ( test == TRUE )
{
#ifdef OLD_DEBUG
bw_error( "ready to call uil_event()" );
#endif
c = uil_event( m_box, c, mo_xsrc, mo_ysrc, x_pos, y_pos, type,
&item );
switch( c )
{
case EVENT_SELECTED:
carry_on = FALSE;
break;
case EVENT_EXIT:
item = TK_EXIT;
carry_on = FALSE;
break;
case EVENT_ERROR:
bw_error( "Error return from uil_event()" );
carry_on = FALSE;
break;
case EVENT_NULL:
default:
test = FALSE;
break;
}
}
ui_poll();
} /* end of main list loop */
#ifdef OLD_DEBUG
bw_error( "Ready to deactivate list box" );
#endif
uil_deactivate( m_box, type );
#ifdef OLD_DEBUG
bw_error( "List box deactivated" );
#endif
return item;
}
/****************************************************************
uil_draw() - draw a list box
****************************************************************/
uil_draw( type, x1, y1, x2, y2, title, number, titles,
foreground, background, highlight, m_box )
int type, x1, y1, x2, y2, foreground, background,
highlight, number;
char *title;
char **titles;
struct menu_box *m_box;
{
register int y;
#ifdef OLD_DEBUG
ui_debug( "entered uil_draw()" );
#endif
/* initial assignments */
m_box->current = 0;
m_box->x_pos = m_box->y_pos = m_box->y_start = 0;
m_box->y_logical = m_box->number = number;
m_box->x_items = m_box->x_logical = 1;
m_box->ysize = ui_grwind->fysize + EXTENSION;
m_box->type = type;
m_box->d_titles = titles;
m_box->x_start = 0;
if ( m_box->is_drawn == FALSE )
{
/* assign colors to structure */
m_box->fore = foreground;
m_box->back = background;
m_box->high = highlight;
/* draw the menu window */
if ( m_box->window == NULL )
{
switch( m_box->type )
{
case MENU_SLIDERS:
#ifdef OLD_DEBUG
sprintf( bw_ebuf, "make slider window %d %d %d %d",
x1, y1, x2, y2 );
bw_debug( bw_ebuf );
#endif
m_box->window = ui_window( x1, y1,
x2, y2, TRUE,
highlight, foreground,
title, TRUE, BLACK,
FALSE, BLACK, background,
SOLID, BUT_CLOSE | BUT_MOVE | BUT_RESIZE );
#ifdef OLD_DEBUG
sprintf( bw_ebuf, "made slider window %d %d %d %d",
m_box->window->x1, m_box->window->y1, m_box->window->x2, m_box->window->y2 );
bw_debug( bw_ebuf );
#endif
break;
case MENU_TITLED:
y = ( m_box->y_logical * m_box->ysize )
+ ( ui_grwind->fysize * 3 );
m_box->window = ui_window( x1, y2 - y,
x2, y2, TRUE,
highlight, foreground,
title, TRUE, BLACK,
TRUE, BLACK, background,
SOLID, BUT_CLOSE | BUT_MOVE | BUT_RESIZE );
break;
case MENU_PLAIN:
default:
#ifdef OLD_DEBUG
sprintf( ui_tbuf, "called uil_draw(): %d %d %d %d (xmax %d) (ymax %d)",
x1, y2 - y,
x2, y2, ui_grwind->xmax, ui_grwind->ymax );
ui_debug( ui_tbuf );
#endif
y = ( m_box->y_logical * m_box->ysize )
+ ( ui_grwind->fysize );
m_box->window = ui_window( x1, y2 - y,
x2, y2, FALSE,
background, foreground,
title, FALSE, BLACK,
TRUE, BLACK, background,
SOLID, 0 );
break;
}
}
else
{
ui_rewindow( m_box->window, title );
}
/* display the menu */
uil_display( m_box );
}
}
/****************************************************************
uil_activate() Activate a list box
****************************************************************/
uil_activate( m_box, type, item )
struct menu_box *m_box;
int type, item;
{
register int x, y;
int carry_on;
#ifdef DEBUG
if ( m_box->d_titles == NULL )
{
bw_error( "Programmer error: menu box has not been drawn!" );
return FALSE;
}
#endif
if ( item > m_box->number )
{
item = 0;
}
if ( item == 0 )
{
m_box->x_start = m_box->y_start = m_box->x_pos = m_box->y_pos
= m_box->current = 0;
}
else if ( item != m_box->current )
{
m_box->current = item;
/* calculate y_start */
y = 0;
carry_on = TRUE;
if ( m_box->y_logical <= m_box->y_items )
{
y = 0;
}
else while( ( y < m_box->y_logical ) && ( carry_on == TRUE ))
{
if ( (( m_box->x_logical * y ) +
( m_box->x_logical * m_box->y_items )) > item )
{
carry_on = FALSE;
}
else
{
++y;
}
}
/* calculate x_start */
x = 0;
carry_on = TRUE;
if ( m_box->x_logical <= m_box->x_items )
{
x = 0;
#ifdef OLD_DEBUG
sprintf( ui_tbuf, "x_logical <= x_items" );
ui_wtitle( m_box->window, ui_tbuf );
ui_wait();
#endif
}
else while( ( x < m_box->x_logical ) && ( carry_on == TRUE ))
{
#ifdef OLD_DEUG
sprintf( ui_tbuf, "item <> x_logical = %d", item % m_box->x_logical );
ui_wtitle( m_box->window, ui_tbuf );
ui_wait();
sprintf( ui_tbuf, "trying %d", x );
ui_wtitle( m_box->window, ui_tbuf );
ui_wait();
#endif
if (( m_box->x_items + x ) > ( item % m_box->x_logical ))
{
carry_on = FALSE;
}
else
{
++x;
}
}
#ifdef OLD_DEBUG
sprintf( ui_tbuf, "i %d; x %d; y %d", item, x, y );
ui_wtitle( m_box->window, ui_tbuf );
#endif
m_box->y_start = y;
m_box->x_start = x;
m_box->y_pos = ( item / m_box->x_logical ) - m_box->y_start;
m_box->x_pos = ( item % m_box->x_logical ) - m_box->x_start;
uil_display( m_box );
}
/* display the exit button */
if ( type != MENU_PLAIN )
{
#ifdef USE_ICONS
#else
ui_fbox( m_box->window->bt_x1, m_box->window->bt_y1,
m_box->window->bt_x2, m_box->window->bt_y2, BLACK, SOLID );
ui_fbox( m_box->window->bt_x1 + 1, m_box->window->bt_y1 + 1,
m_box->window->bt_x2 - 1, m_box->window->bt_y2 - 1, WHITE, GRID );
#endif
}
/* show current item selected */
uil_item( m_box, m_box->current,
m_box->d_titles[ m_box->current ], TRUE );
}
/****************************************************************
uil_deactivate() Deactivate a list menu box
****************************************************************/
uil_deactivate( m_box, type )
struct menu_box *m_box;
int type;
{
#ifdef OLD_DEBUG
bw_error( "enter deactivate" );
#endif
uil_item( m_box, m_box->current,
m_box->d_titles[ m_box->current ], FALSE );
#ifdef OLD_DEBUG
bw_error( "exit deactivate" );
#endif
}
/****************************************************************
uil_event() Query if an event affects a list box
****************************************************************/
uil_event( m_box, key, mo_xsrc, mo_ysrc, mo_xdest, mo_ydest, type, item )
struct menu_box *m_box;
int key, mo_xsrc, mo_ysrc, mo_xdest, mo_ydest, type;
int *item;
{
static int how_far, x_sel, y_sel;
register int c;
how_far = 0;
c = ui_event( m_box, key, mo_xsrc, mo_ysrc, mo_xdest, mo_ydest,
&how_far, &x_sel, &y_sel );
switch( c )
{
case FALSE:
*item = TK_EXIT;
return EVENT_NULL;
case CR:
case LF:
uil_exit( m_box, type );
*item = m_box->current;
return EVENT_SELECTED;
break;
case KB_DOWN:
if ( m_box->current < ( m_box->number - 1 ))
{
uil_item( m_box, m_box->current,
m_box->d_titles[ m_box->current ],
FALSE );
++m_box->current;
++m_box->y_pos;
if ( m_box->y_pos == m_box->y_items )
{
++m_box->y_start;
--m_box->y_pos;
uil_display( m_box );
uil_item( m_box, m_box->current,
m_box->d_titles[ m_box->current ],
TRUE );
}
else
{
uil_item( m_box, m_box->current,
m_box->d_titles[ m_box->current ],
TRUE );
}
}
*item = 0;
return EVENT_NULL;
break;
case KB_UP:
if ( m_box->current > 0 )
{
uil_item( m_box, m_box->current,
m_box->d_titles[ m_box->current ],
FALSE );
--m_box->current;
--m_box->y_pos;
if ( ( m_box->y_start > 0 ) && ( m_box->y_pos < 0 ))
{
--m_box->y_start;
++m_box->y_pos;
uil_display( m_box );
uil_item( m_box, m_box->current,
m_box->d_titles[ m_box->current ],
TRUE );
}
else
{
uil_item( m_box, m_box->current,
m_box->d_titles[ m_box->current ],
TRUE );
}
}
*item = 0;
return EVENT_NULL;
break;
case ESCAPE:
case MO_EXIT:
uil_exit( m_box, type );
*item = 0;
return TK_EXIT;
break;
case MO_UP:
if ( m_box->y_start > 0 )
{
while ( ( m_box->y_start - how_far ) < 0 )
{
--how_far;
}
m_box->y_start -= how_far;
m_box->current -= how_far;
uil_display( m_box );
uil_item( m_box, m_box->current,
m_box->d_titles[ m_box->current ],
TRUE );
}
*item = 0;
return EVENT_NULL;
break;
case MO_DN:
if ( ( m_box->y_start + m_box->y_items )
< m_box->number )
{
while ( ( m_box->y_start + how_far + m_box->y_items )
> m_box->number )
{
--how_far;
}
m_box->y_start += how_far;
m_box->current += how_far;
uil_display( m_box );
uil_item( m_box, m_box->current,
m_box->d_titles[ m_box->current ],
TRUE );
}
*item = 0;
return EVENT_NULL;
break;
case MO_SEL:
if ( y_sel == m_box->y_pos )
{
uil_exit( m_box, type );
*item = m_box->current;
return EVENT_SELECTED;
}
uil_item( m_box, m_box->current,
m_box->d_titles[ m_box->current ], FALSE );
m_box->current = m_box->y_start + y_sel;
m_box->y_pos = y_sel;
uil_item( m_box, m_box->current,
m_box->d_titles[ m_box->current ], TRUE );
*item = 0;
return EVENT_NULL;
break;
default:
*item = 0;
return EVENT_NULL;
break;
}
}
/****************************************************************
uil_display() Show all items in a list box
****************************************************************/
uil_display( m_box )
struct menu_box *m_box;
{
register int c, v;
int x, y;
if ( m_box->is_drawn == FALSE )
{
switch( m_box->type )
{
case MENU_SLIDERS:
uil_sliders( m_box );
break;
case MENU_TITLED:
case MENU_PLAIN:
default:
uil_plain( m_box );
break;
}
}
/* calculate visible lines */
m_box->y_items = ( m_box->i_y2 - m_box->i_y1 )
/ m_box->ysize;
m_box->xsize = ( m_box->i_x2 - m_box->i_x1 ) / m_box->x_logical;
if ( m_box->type == MENU_SLIDERS )
{
/* calculate increments for elevators */
x = ui_grwind->ymax / 15;
y = ( x * gr_pxsize ) / gr_pysize;
if ( m_box->y_logical <= m_box->y_items )
{
m_box->vel_inc = 1;
}
else
{
m_box->vel_inc = ((( m_box->ve_y2 - ( m_box->ve_y1 + y ))
* INC_ACCURACY )
/ ( m_box->y_logical - m_box->y_items ));
}
if ( m_box->vel_inc <= 0 ) /* increment cannot be <= 0 */
{
m_box->vel_inc = 1;
}
if ( m_box->x_logical <= m_box->x_items )
{
m_box->hel_inc = 1;
}
else
{
m_box->hel_inc = ((( m_box->he_x2 - ( m_box->he_x1 + x ))
* INC_ACCURACY )
/ ( m_box->x_logical - m_box->x_items ));
}
if ( m_box->vel_inc <= 0 ) /* increment cannot be <= 0 */
{
m_box->vel_inc = 1;
}
uil_vel( m_box ); /* show vertical elevator */
if ( m_box->is_drawn == FALSE )
{
uil_hel( m_box ); /* show horizontal elevator */
}
}
c = 0;
v = m_box->y_start;
while ( ( c < m_box->y_items ) && ( v < m_box->number ))
{
uil_item( m_box, v, m_box->d_titles[ v ], FALSE );
++c;
++v;
}
m_box->is_drawn = TRUE;
}
/****************************************************************
uil_item() Show a particular item in a list box
****************************************************************/
uil_item( m_box, item, text, selected )
struct menu_box *m_box;
int item, selected;
char *text;
{
int x1, y1, x2, y2;
x1 = m_box->i_x1;
y1 = m_box->i_y2 - ( m_box->ysize *
( 1 + item - m_box->y_start ));
x2 = m_box->i_x2;
y2 = m_box->i_y2 - ( m_box->ysize *
( item - m_box->y_start ));
if ( selected == TRUE )
{
ui_fbox( x1, y1, x2, y2, m_box->fore, SOLID );
ui_str( x1, y1 + EXTENSION, x2, m_box->fore, m_box->back,
text );
}
else
{
ui_fbox( x1, y1, x2, y2, m_box->back, SOLID );
ui_str( x1, y1 + EXTENSION, x2, m_box->back, m_box->fore,
text );
}
}
/****************************************************************
uil_vel() Show vertical elevator
****************************************************************/
uil_vel( m_box )
struct menu_box *m_box;
{
int y_pos;
/* return if no area (box too small ) */
if ( m_box->ve_y2 <= m_box->ve_y1 )
{
#ifdef OLD_DEBUG
bw_debug( "No room for vertical slider" );
#endif
return FALSE;
}
#ifdef OLD_DEBUG
bw_debug( "Drawing vertical slider" );
#endif
/* first blank the elevator area */
ui_fbox( m_box->vs_x1, m_box->ve_y1, m_box->vs_x2, m_box->ve_y2,
BLACK, SOLID );
ui_fbox( m_box->vs_x1 + 1, m_box->ve_y1 + 1,
m_box->vs_x2 - 1, m_box->ve_y2 - 1,
m_box->back, GRID );
/* calculate size and current position */
y_pos = m_box->ve_y2 - (( m_box->y_start * m_box->vel_inc ) / INC_ACCURACY );
m_box->vel_y1 = y_pos - ( m_box->ve_y1 - m_box->vs_y1 );
m_box->vel_x1 = m_box->vs_x1;
m_box->vel_x2 = m_box->vs_x2;
m_box->vel_y2 = y_pos;
#ifdef OLD_DEBUG
sprintf( bw_ebuf, "vel y1 %d y2 %d y_pos %d",
m_box->vel_y1, m_box->vel_y2, y_pos );
bw_debug( bw_ebuf );
#endif
/* draw the elevator */
#ifdef USE_ICONS
ui_pbmcenter( ui_screen, m_box->vel_x1, m_box->vel_y1, m_box->vel_x2,
m_box->vel_y2, &ui_elicon );
#else
ui_fbox( m_box->vel_x1 + EL_OFFSET, m_box->vel_y1 + EL_OFFSET,
m_box->vel_x2 - EL_OFFSET, m_box->vel_y2 - EL_OFFSET,
BLACK, SOLID );
ui_fbox( m_box->vel_x1 + EL_OFFSET + 1,
m_box->vel_y1 + EL_OFFSET + 1,
m_box->vel_x2 - ( EL_OFFSET + 1 ),
m_box->vel_y2 - ( EL_OFFSET + 1 ),
m_box->back, SOLID );
gr_circle( ui_screen,
m_box->vel_x1 + (( m_box->vel_x2 - m_box->vel_x1 ) / 2 ),
m_box->vel_y1 + ( ( m_box->ve_y1 - m_box->vs_y1 ) / 2 ),
( m_box->ve_y1 - m_box->vs_y1 ) / 4, BLACK, SOLID );
gr_circle( ui_screen,
m_box->vel_x1 + (( m_box->vel_x2 - m_box->vel_x1 ) / 2 ),
m_box->vel_y1 + ( ( m_box->ve_y1 - m_box->vs_y1 ) / 2 ),
( m_box->ve_y1 - m_box->vs_y1 ) / 4, m_box->high, GRID );
#endif
}
/****************************************************************
uil_hel() Show horizontal elevator
****************************************************************/
uil_hel( m_box )
struct menu_box *m_box;
{
int x_pos;
/* first blank the elevator area */
ui_fbox( m_box->he_x1, m_box->hs_y1,
m_box->he_x2, m_box->hs_y2,
BLACK, SOLID );
ui_fbox( m_box->he_x1 + 1, m_box->hs_y1,
m_box->he_x2 - 1, m_box->hs_y2,
m_box->back, GRID );
/* calculate size and current position */
m_box->hel_x1 = x_pos = m_box->he_x1
+ (( m_box->hel_inc * m_box->x_start ) / INC_ACCURACY );
m_box->hel_x2 = m_box->hel_x1 + ( m_box->hs_x2 - m_box->he_x2 );
m_box->hel_y1 = m_box->hs_y1;
m_box->hel_y2 = m_box->hs_y2;
#ifdef OLD_DEBUG
sprintf( ui_tbuf, "he_x1 = %d, inc * start = %d, inc = %d, start = %d, x_pos = %d, hel = %d",
m_box->he_x1, ( m_box->hel_inc * start ) / INC_ACCURACY,
m_box->hel_inc, m_box->x_start, x_pos, m_box->hel_x1 );
ui_wtitle( m_box->window, ui_tbuf );
ui_wait();
#endif
/* draw the elevator */
#ifdef USE_ICONS
ui_pbmcenter( ui_screen, m_box->hel_x1, m_box->hel_y1, m_box->hel_x2,
m_box->hel_y2, &ui_elicon );
#else
ui_fbox( m_box->hel_x1 + EL_OFFSET, m_box->hel_y1 + EL_OFFSET,
m_box->hel_x2 - EL_OFFSET, m_box->hel_y2 - EL_OFFSET,
BLACK, SOLID );
ui_fbox( m_box->hel_x1 + EL_OFFSET + 1,
m_box->hel_y1 + EL_OFFSET + 1,
m_box->hel_x2 - ( EL_OFFSET + 1),
m_box->hel_y2 - (EL_OFFSET + 1),
m_box->back, SOLID );
gr_circle( ui_screen,
m_box->hel_x1 + ( ( m_box->hs_x2 - m_box->he_x2 ) / 2 ),
m_box->hel_y1 + ( ( m_box->hel_y2 - m_box->hel_y1 ) / 2 ),
( m_box->hel_y2 - m_box->hel_y1 ) / 4,
BLACK, SOLID );
gr_circle( ui_screen,
m_box->hel_x1 + ( ( m_box->hs_x2 - m_box->he_x2 ) / 2 ),
m_box->hel_y1 + ( ( m_box->hel_y2 - m_box->hel_y1 ) / 2 ),
( m_box->hel_y2 - m_box->hel_y1 ) / 4,
m_box->high, GRID );
#endif
}
uil_exit( m_box, type )
struct menu_box *m_box;
int type;
{
/* blank the exit button */
if ( type != MENU_PLAIN )
{
#ifdef USE_ICONS
#else
ui_fbox( m_box->window->bt_x1, m_box->window->bt_y1,
m_box->window->bt_x2, m_box->window->bt_y2, BLACK, SOLID );
#endif
}
/* fill elevators with grid */
if ( type == MENU_SLIDERS )
{
if ( m_box->ve_y2 > m_box->ve_y1 )
{
ui_fbox( m_box->vs_x1, m_box->ve_y1,
m_box->vs_x2, m_box->ve_y2, BLACK, SOLID ); /* blank */
ui_fbox( m_box->vs_x1 + 1, m_box->ve_y1 + 1,
m_box->vs_x2 - 1, m_box->ve_y2 - 1,
m_box->back, GRID );
}
ui_fbox( m_box->he_x1, m_box->hs_y1,
m_box->he_x2, m_box->hs_y2, BLACK, SOLID ); /* blank */
ui_fbox( m_box->he_x1 + 1, m_box->hs_y1,
m_box->he_x2 - 1, m_box->hs_y2,
m_box->back, GRID );
}
}
/****************************************************************
ui_event() Query if keyboard or mouse actions affect
a list or icon menu box
****************************************************************/
ui_event( m_box, key, mo_xsrc, mo_ysrc, mo_xdest, mo_ydest,
how_far, x_sel, y_sel )
struct menu_box *m_box;
int key, mo_xsrc, mo_ysrc, mo_xdest, mo_ydest;
int *how_far, *x_sel, *y_sel;
{
register int c, d;
/* if a key is available, simply return it */
if ( key != FALSE )
{
return key;
}
/* else presume that a mouse event has occurred */
/* if the destination point is not within the window check to see if
the source point is */
else if ( uil_bounds( mo_xdest, mo_ydest, m_box->window->x1,
m_box->window->y1, m_box->window->x2, m_box->window->y2 ) == FALSE )
{
if ( uil_bounds( mo_xsrc, mo_ysrc, m_box->window->x1,
m_box->window->y1, m_box->window->x2, m_box->window->y2 ) == TRUE )
{
/* test for selection bounds */
for ( c = 0; c < m_box->y_items; ++c )
{
for ( d = 0; d < m_box->x_items; ++d )
{
if ( uil_bounds( mo_xsrc, mo_ysrc,
m_box->i_x1 + ( d * m_box->xsize ),
m_box->i_y2 - ( ( c + 1 ) * m_box->ysize ),
m_box->i_x1 + ( ( d + 1 ) * m_box->xsize ),
m_box->i_y2 - ( c * m_box->ysize ) ) == TRUE )
{
*y_sel = c;
*x_sel = d;
return MO_SRC;
}
}
}
/* selection bounds tests failed */
return FALSE;
}
else
{
return FALSE;
}
}
/* Check to see if source is within range of the vertical elevator */
else if ( uil_bounds( mo_xsrc, mo_ysrc, m_box->vel_x1, m_box->vel_y1,
m_box->vel_x2, m_box->vel_y2 ) == TRUE )
{
if ( ( mo_ysrc - mo_ydest ) == 0 )
{
return FALSE;
}
else if ( ( mo_ysrc - mo_ydest ) > 0 )
{
*how_far = (( mo_ysrc - mo_ydest )
* INC_ACCURACY )
/ m_box->vel_inc;
return MO_DN;
}
else
{
*how_far = (( mo_ydest - mo_ysrc )
* INC_ACCURACY )
/ m_box->vel_inc;
return MO_UP;
}
}
if ( uil_bounds( mo_xsrc, mo_ysrc, m_box->hel_x1, m_box->hel_y1,
m_box->hel_x2, m_box->hel_y2 ) == TRUE )
{
if ( ( mo_xsrc - mo_xdest ) == 0 )
{
return FALSE;
}
else if ( ( mo_xsrc - mo_xdest ) > 0 )
{
*how_far = (( mo_xsrc - mo_xdest )
* INC_ACCURACY )
/ m_box->hel_inc;
return MO_LEFT;
}
else
{
*how_far = (( mo_xdest - mo_xsrc )
* INC_ACCURACY )
/ m_box->hel_inc;
return MO_RIGHT;
}
}
/* test for exit button bounds */
if ( uil_bounds( mo_xdest, mo_ydest, m_box->window->bt_x1, m_box->window->bt_y1,
m_box->window->bt_x2, m_box->window->bt_y2 ) == TRUE )
{
return MO_EXIT;
}
/* test for up arrow bounds */
if ( uil_bounds( mo_xdest, mo_ydest, m_box->vs_x1, m_box->ve_y2,
m_box->vs_x2, m_box->vs_y2 ) == TRUE )
{
*how_far = 1;
return MO_UP;
}
/* test for down arrow bounds */
if ( uil_bounds( mo_xdest, mo_ydest, m_box->vs_x1, m_box->vs_y1,
m_box->vs_x2, m_box->ve_y1 ) == TRUE )
{
*how_far = 1;
return MO_DN;
}
/* test for left arrow bounds */
if ( uil_bounds( mo_xdest, mo_ydest, m_box->hs_x1, m_box->hs_y1,
m_box->he_x1, m_box->hs_y2 ) == TRUE )
{
*how_far = 1;
return MO_LEFT;
}
/* test for right arrow bounds */
if ( uil_bounds( mo_xdest, mo_ydest, m_box->he_x2, m_box->hs_y1,
m_box->hs_x2, m_box->hs_y2 ) == TRUE )
{
*how_far = 1;
return MO_RIGHT;
}
/* test for selection bounds */
for ( c = 0; c < m_box->y_items; ++c )
{
for ( d = 0; d < m_box->x_items; ++d )
{
if ( uil_bounds( mo_xdest, mo_ydest,
m_box->i_x1 + ( d * m_box->xsize ),
m_box->i_y2 - ( ( c + 1 ) * m_box->ysize ),
m_box->i_x1 + ( ( d + 1 ) * m_box->xsize ),
m_box->i_y2 - ( c * m_box->ysize ) ) == TRUE )
{
*y_sel = c;
*x_sel = d;
return MO_SEL;
}
}
}
}
/****************************************************************
uil_bounds() See if x and y are within bounds of x1, y1, x2, y2
****************************************************************/
uil_bounds( x, y, x1, y1, x2, y2 )
int x, y, x1, y1, x2, y2;
{
if ( x < x1 )
{
return FALSE;
}
if ( x > x2 )
{
return FALSE;
}
if ( y < y1 )
{
return FALSE;
}
if ( y > y2 )
{
return FALSE;
}
return TRUE;
}
/****************************************************************
uil_sliders() Calculate and draw sliders
for menu/icon box
****************************************************************/
uil_sliders( m_box )
struct menu_box *m_box;
{
int midv, midh, toph, both, leftv, rightv;
int halfh, halfv, x, y;
/* assign sizes to icon area and sliders */
x = ui_grwind->fxsize * SL_YSIZE;
if ( x > SL_XMAX )
{
x = SL_XMAX;
}
y = (( x * gr_pxsize ) * ACC ) / ( gr_pysize * ACC );
#ifdef OLD_DEBUG
sprintf( bw_ebuf, "SL_XMAX = %d; x = %d, y = %d", SL_XMAX, x, y );
bw_debug( bw_ebuf );
#endif
m_box->i_x1 = m_box->window->u_x1 + 2;
m_box->i_y1 = m_box->window->u_y1 + y;
m_box->i_x2 = m_box->window->u_x2 - ( x + 3 );
m_box->i_y2 = m_box->window->u_y2 - 1;
m_box->vs_x1 = m_box->window->u_x2 - ( x + 1 );
m_box->vs_y1 = m_box->i_y1;
m_box->vs_x2 = m_box->window->u_x2;
m_box->vs_y2 = m_box->window->u_y2 - 1;
m_box->hs_x1 = m_box->window->u_x1 + 1;
m_box->hs_y1 = m_box->window->u_y1;
m_box->hs_x2 = m_box->i_x2;
m_box->hs_y2 = m_box->i_y1 - 1;
m_box->ve_y1 = m_box->vs_y1 + y;
m_box->ve_y2 = m_box->vs_y2 - y;
m_box->he_x1 = m_box->window->u_x1 + x;
m_box->he_x2 = m_box->hs_x2 - x;
#ifdef OLD_DEBUG
sprintf( bw_ebuf, "made horizontal slider %d %d %d %d",
m_box->hs_x1, m_box->hs_y1, m_box->hs_x2, m_box->hs_y2 );
bw_debug( bw_ebuf );
#endif
/* outline the areas */
gr_line( ui_screen, m_box->window->u_x1, m_box->hs_y2,
m_box->vs_x2, m_box->hs_y2, m_box->fore, SOLID );
--m_box->hs_y2;
gr_line( ui_screen, m_box->vs_x1, m_box->hs_y1,
m_box->vs_x1, m_box->window->u_y2, m_box->fore, SOLID );
++m_box->vs_x1;
/* demarcate arrow areas */
gr_line( ui_screen, m_box->he_x1, m_box->hs_y1,
m_box->he_x1, m_box->hs_y2, m_box->fore, SOLID );
gr_line( ui_screen, m_box->he_x2, m_box->hs_y1,
m_box->he_x2, m_box->hs_y2, m_box->fore, SOLID );
gr_line( ui_screen, m_box->vs_x1, m_box->ve_y1,
m_box->vs_x2, m_box->ve_y1, m_box->fore, SOLID );
gr_line( ui_screen, m_box->vs_x1, m_box->ve_y2,
m_box->vs_x2, m_box->ve_y2, m_box->fore, SOLID );
/* calculate some midpoints */
midh = m_box->hs_y1 + (( m_box->hs_y2 - m_box->hs_y1 ) / 2 );
toph = m_box->hs_y2 - (( m_box->hs_y2 - m_box->hs_y1 ) / 3 );
both = m_box->hs_y1 + (( m_box->hs_y2 - m_box->hs_y1 ) / 3 );
midv = m_box->vs_x1 + (( m_box->vs_x2 - m_box->vs_x1 ) / 2 );
leftv = m_box->vs_x1 + (( m_box->vs_x2 - m_box->vs_x1 ) / 3 );
rightv = m_box->vs_x2 - (( m_box->vs_x2 - m_box->vs_x1 ) / 3 );
/* left arrow */
ui_fbox( m_box->hs_x1, m_box->hs_y1, m_box->he_x1, m_box->hs_y2,
m_box->high, SOLID );
#ifdef USE_ICONS
ui_pbmcenter( ui_screen, m_box->hs_x1, m_box->hs_y1, m_box->he_x1, m_box->hs_y2,
&ui_lefticn );
#else
halfh = m_box->hs_x1 + (( m_box->he_x1 - m_box->hs_x1 ) / 2 );
uil_arrow( m_box,
m_box->hs_x1, midh,
halfh, m_box->hs_y1 + 1,
halfh, both,
m_box->he_x1, both,
m_box->he_x1, toph,
halfh, toph,
halfh, m_box->hs_y2 - 1,
m_box->hs_x1, midh );
gr_line( ui_screen, halfh + 1, m_box->hs_y1 + 1,
halfh + 1, both, m_box->fore, SOLID ); /* shadow */
gr_line( ui_screen, halfh + 1, toph,
halfh + 1, m_box->hs_y2 - 1, m_box->fore, SOLID );
gr_line( ui_screen, halfh, both - 1,
m_box->he_x1, both - 1, m_box->fore, SOLID );
#endif
/* right arrow */
ui_fbox( m_box->he_x2, m_box->hs_y1, m_box->hs_x2, m_box->hs_y2,
m_box->high, SOLID );
#ifdef USE_ICONS
ui_pbmcenter( ui_screen, m_box->he_x2, m_box->hs_y1, m_box->hs_x2, m_box->hs_y2,
&ui_righticn );
#else
halfh = m_box->he_x2 + (( m_box->hs_x2 - m_box->he_x2 ) / 2 );
uil_arrow( m_box,
m_box->hs_x2, midh,
halfh, m_box->hs_y1 + 1,
halfh, both,
m_box->he_x2, both,
m_box->he_x2, toph,
halfh, toph,
halfh, m_box->hs_y2 - 1,
m_box->hs_x2, midh );
gr_line( ui_screen, halfh, both - 1,
m_box->he_x2, both - 1, m_box->fore, SOLID );
gr_line( ui_screen, halfh + 1, m_box->hs_y1 + 1,
m_box->hs_x2, midh - 1, m_box->fore, SOLID ); /* shadow */
#endif
/* up arrow */
ui_fbox( m_box->vs_x1, m_box->ve_y2, m_box->vs_x2, m_box->vs_y2,
m_box->high, SOLID );
#ifdef USE_ICONS
ui_pbmcenter( ui_screen, m_box->vs_x1, m_box->ve_y2, m_box->vs_x2, m_box->vs_y2,
&ui_upicn );
#else
halfv = m_box->ve_y2 + (( m_box->vs_y2 - m_box->ve_y2 ) / 2 );
uil_arrow( m_box,
midv, m_box->vs_y2, /* point 1 */
m_box->vs_x1 + 1, halfv, /* point 2 */
leftv, halfv, /* point 3 */
leftv, m_box->ve_y2, /* point 4 */
rightv, m_box->ve_y2, /* point 5 */
rightv, halfv, /* point 6 */
m_box->vs_x2 - 1, halfv, /* point 7 */
midv, m_box->vs_y2 ); /* point 8 */
gr_line( ui_screen, m_box->vs_x1 + 1, halfv - 1,
leftv, halfv - 1, m_box->fore, SOLID );
gr_line( ui_screen, rightv, halfv - 1,
m_box->vs_x2 - 1, halfv - 1, m_box->fore, SOLID );
gr_line( ui_screen, rightv + 1, m_box->ve_y2,
rightv + 1, halfv, m_box->fore, SOLID ); /* shadow */
#endif
/* down arrow */
ui_fbox( m_box->vs_x1, m_box->vs_y1, m_box->vs_x2, m_box->ve_y1,
m_box->high, SOLID );
#ifdef USE_ICONS
ui_pbmcenter( ui_screen, m_box->vs_x1, m_box->vs_y1, m_box->vs_x2, m_box->ve_y1,
&ui_downicn );
#else
halfv = m_box->vs_y1 + (( m_box->ve_y1 - m_box->vs_y1 ) / 2 );
uil_arrow( m_box,
midv, m_box->vs_y1, /* point 1 */
m_box->vs_x1 + 1, halfv, /* point 2 */
leftv, halfv, /* point 3 */
leftv, m_box->ve_y1, /* point 4 */
rightv, m_box->ve_y1, /* point 5 */
rightv, halfv, /* point 6 */
m_box->vs_x2 - 1, halfv, /* point 7 */
midv, m_box->vs_y1 ); /* point 8 */
gr_line( ui_screen, rightv + 1, halfv,
rightv + 1, m_box->ve_y1, m_box->fore, SOLID );
gr_line( ui_screen, midv + 1, m_box->vs_y1,
m_box->vs_x2 - 1, halfv - 1, m_box->fore, SOLID ); /* shadow */
#endif
/* blank elevator areas with grid */
#ifdef OLD_DEBUG
sprintf( bw_ebuf, "draw horizontal slider %d %d %d %d",
m_box->hs_x1, m_box->hs_y1, m_box->hs_x2, m_box->hs_y2 );
bw_debug( bw_ebuf );
#endif
if ( m_box->hs_y2 > m_box->hs_y1 )
{
/* gr_rectangle( ui_screen, m_box->he_x1, m_box->hs_y1,
m_box->he_x2, m_box->hs_y2, m_box->fore, HOLLOW ); */
gr_rectangle( ui_screen, m_box->he_x1 + 1, m_box->hs_y1,
m_box->he_x2 - 1, m_box->hs_y2, m_box->fore, GRID );
#ifdef OLD_DEBUG
sprintf( bw_ebuf, "made horizontal slider %d %d %d %d",
m_box->hs_x1, m_box->hs_y1, m_box->hs_x2, m_box->hs_y2 );
bw_debug( bw_ebuf );
#endif
}
if ( m_box->ve_y2 > m_box->ve_y1 )
{
gr_rectangle( ui_screen, m_box->vs_x1, m_box->ve_y1,
m_box->vs_x2, m_box->ve_y2, m_box->fore, HOLLOW );
gr_rectangle( ui_screen, m_box->vs_x1 + 1, m_box->ve_y1 + 1,
m_box->vs_x2 - 1, m_box->ve_y2 - 1, m_box->fore, GRID );
}
}
/****************************************************************
uil_arrow() Draw an arrow for the slider box
****************************************************************/
uil_arrow( m_box,
x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, x6, y6, x7, y7, x8, y8 )
struct menu_box *m_box;
int x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, x6, y6, x7, y7, x8, y8;
{
gr_line( ui_screen, x1, y1, x2, y2, m_box->fore, SOLID );
gr_line( ui_screen, x2, y2, x3, y3, m_box->fore, SOLID );
gr_line( ui_screen, x3, y3, x4, y4, m_box->fore, SOLID );
gr_line( ui_screen, x4, y4, x5, y5, m_box->fore, SOLID );
gr_line( ui_screen, x5, y5, x6, y6, m_box->fore, SOLID );
gr_line( ui_screen, x6, y6, x7, y7, m_box->fore, SOLID );
gr_line( ui_screen, x7, y7, x8, y8, m_box->fore, SOLID );
}
/****************************************************************
uil_plain() Calculate sizes
for plain menu box
****************************************************************/
uil_plain( m_box )
struct menu_box *m_box;
{
/* assign sizes to icon area */
m_box->i_x1 = m_box->window->u_x1 + 2;
m_box->i_y1 = m_box->window->u_y1;
m_box->i_x2 = m_box->window->u_x2 - 2;
m_box->i_y2 = m_box->window->u_y2 - 1;
m_box->vs_x1 = 1;
m_box->vs_y1 = 1;
m_box->vs_x2 = 1;
m_box->vs_y2 = 1;
m_box->hs_x1 = 1;
m_box->hs_y1 = 1;
m_box->hs_x2 = 1;
m_box->hs_y2 = 1;
m_box->ve_y1 = 1;
m_box->ve_y2 = 1;
m_box->he_x1 = 1;
m_box->he_x2 = 1;
}